﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PlanningGIS.Util;
using DevComponents.DotNetBar;
using DevComponents.Editors;

namespace PlanningGIS.Win.Controls
{
    /// <summary>
    /// 坐标值输入控件
    /// </summary>
    public partial class CoordinateInput : UserControl
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public CoordinateInput()
        {
            InitializeComponent();
            //SetStyle(ControlStyles.UserPaint, true);
            //SetStyle(ControlStyles.DoubleBuffer, true);
            //SetStyle(ControlStyles.AllPaintingInWmPaint, true);            
        }
                
        /// <summary>
        /// 加载控件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CoordinateInput_Load(object sender, EventArgs e)
        {
            txtDegree.ValueChanged += _ValueChanged;
            txtMeter.ValueChanged += _ValueChanged;
            txtMinute.ValueChanged += _ValueChanged;
            txtSecond.ValueChanged += _ValueChanged;

            txtDegree.LostFocus += _LostFocus;
            txtMeter.LostFocus += _LostFocus;
            txtMinute.LostFocus += _LostFocus;
            txtSecond.LostFocus += _LostFocus;
        }

        /// <summary>
        /// 当前值改变事件
        /// </summary>
        public event EventHandler ValueChanged = null;

        /// <summary>
        /// 坐标值的单位
        /// </summary>
        private zjgisUnit _Unit = zjgisUnit.DMS;
        /// <summary>
        /// 获取或设置坐标值的单位
        /// </summary>
        [Description("坐标值的单位,默认为度分秒")]
        public zjgisUnit Unit
        {
            get { return _Unit; }
            set
            {
                if (_Unit.Equals(value)) return;
                _Unit = value;
                RefreshControl();
            }
        }

        /// <summary>
        /// 是否允许设置单位
        /// </summary>
        public bool AllowSetUnit
        {
            get { return btnUnit.Enabled; }
            set { btnUnit.Enabled = value; }
        }

        /// <summary>
        /// 之前的值，转化为数值型
        /// </summary>
        private double _OldValue = 0;

        /// <summary>
        /// 获取输入的坐标值
        /// </summary>
        public dynamic Value
        {
            get
            {
                if (Unit == zjgisUnit.DMS)
                {
                    return string.Format("{0}°{1}′{2}″", txtDegree.Value, txtMinute.Value, txtSecond.Value);
                }
                else
                {
                    return txtMeter.Value;
                }
            }
            set
            {
                //_Init = true;
                SetValue(value);
                //_Init = false;
            }
        }

        ///// <summary>
        ///// 是否为初始化状态
        ///// </summary>
        //private bool _Init = true;

        ///// <summary>
        ///// 值是否改变
        ///// </summary>
        //private bool _IsChanged = false;

        /// <summary>
        /// 刷新控件的显示状态
        /// </summary>
        private void RefreshControl()
        {
            txtDegree.Visible = (Unit == zjgisUnit.DMS);
            lblDegree.Visible = (Unit == zjgisUnit.DMS);
            txtMinute.Visible = (Unit == zjgisUnit.DMS);
            lblMinute.Visible = (Unit == zjgisUnit.DMS);
            txtSecond.Visible = (Unit == zjgisUnit.DMS);
            switch (Unit)
            {
                case zjgisUnit.Degree:
                    btnUnit.Text = "°";
                    txtMeter.DisplayFormat = "0.0000000";
                    break;
                case zjgisUnit.DMS:
                    btnUnit.Text = "″";
                    break;
                default:
                    btnUnit.Text = "m";
                    txtMeter.DisplayFormat = "0.000";
                    break;
            }
            txtMeter.Visible = (Unit != zjgisUnit.DMS);
            this.Refresh();
        }

        /// <summary>
        /// 设置坐标的值
        /// </summary>
        /// <param name="value"></param>
        private void SetValue(dynamic value)
        {
            Clear();
            double v = 0;
            if (value is double) v = value;      
            if (value is string)
            {
                if (string.IsNullOrWhiteSpace(value)) return;
                string[] vs = value.Split(new string[] { "°", "′", "″", "度", "分", "秒" }, StringSplitOptions.RemoveEmptyEntries);
                if (vs.Length > 1)
                {
                    txtDegree.Value = int.Parse(vs[0]);
                    txtMinute.Value = int.Parse(vs[1]);
                    txtSecond.Value = 0;
                    if (vs.Length > 2) txtSecond.Value = double.Parse(vs[2]);
                    v = txtDegree.Value + txtMinute.Value / 60.0 + txtSecond.Value / (60 * 60.0);
                    txtMeter.Value = Math.Round(v, 7);
                    _OldValue = v;
                    return;
                }
                if (!double.TryParse(value, out v)) return;
            }
            if (v == 0) return;
            txtMeter.Value = v;
            if (Unit == zjgisUnit.Degree)
            {
                txtDegree.Value = (int)Math.Floor(v);
                v = (v - txtDegree.Value) * 60;
                txtMinute.Value = (int)Math.Floor(v);
                txtSecond.Value = (v - txtMinute.Value) * 60;
            }
            _OldValue = v;
        }

        /// <summary>
        /// 清除值
        /// </summary>
        public void Clear()
        {
            txtDegree.Value = 0;
            txtMinute.Value = 0;
            txtSecond.Value = 0;
            txtMeter.Value = 0;
            _OldValue = 0;
            //_IsChanged = false;
        }

        /// <summary>
        /// 输入框失去焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _LostFocus(object sender, EventArgs e)
        {
            //if (_Init) return;
            if (ValueChanged == null) return;
            double v = GetDoubleValue();
            if (v == _OldValue) return;
            bool changed = false;
            if (txtMeter.Visible) changed=true;
            else
            {
                if (!txtDegree.Focused && !txtMinute.Focused && !txtSecond.Focused) changed = true;
            }
            if (changed)
            {
                _OldValue = v;
                ValueChanged(this, new EventArgs());
            }
        }

        /// <summary>
        /// 值改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ValueChanged(object sender, EventArgs e)
        {
            //if (_Init) return;
            //_IsChanged = true;
        }
          
        /// <summary>
        /// 获取坐标双精度的值
        /// </summary>
        /// <returns></returns>
        public double GetDoubleValue()
        {
            if (Unit != zjgisUnit.DMS)
            {
                return txtMeter.Value;
            }
            else
            {
                return txtDegree.Value + txtMinute.Value / 60.0 + txtSecond.Value / (60 * 60.0); 
            }
        }

        /// <summary>
        /// 重写窗体大小改变事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnResize(EventArgs e)
        {
            this.Height = 21;
            base.OnResize(e);
        }

        /// <summary>
        /// 选择单位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Unit_Click(object sender, EventArgs e)
        {
            string txt = (sender as ButtonItem).Text;
            switch (txt)
            {
                case "°":
                    this.Unit = zjgisUnit.Degree;
                    break;
                case "″":
                    this.Unit = zjgisUnit.DMS;
                    break;
                default :
                    this.Unit = zjgisUnit.Meter;
                    break;
            }
            btnUnit.Text = txt;
        }
 

    }
}
